// 防抖基础
function debounce1(fn, delay){
  let timer = null
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(()=>{
      fn.apply(this,args)
    },delay)
  }
}

// 防抖立即执行
function debounce2(fn, delay,immediate = false){
  let timer = null
  let isInvoke = false
  return function(...args) {
    if (timer) clearTimeout(timer)
    if(immediate && !isInvoke){
      fn.apply(this,args)
      isInvoke = true
    }else {
      timer = setTimeout(()=>{
        fn.apply(this,args)
        isInvoke = false
      },delay)
    }
  }
}

// 防抖取消功能
function debounce3(fn, delay,immediate = false){
  let timer = null
  let isInvoke = false
  const _debounce = function(...args) {
    if (timer) clearTimeout(timer)
    if(immediate && !isInvoke){
      fn.apply(this,args)
      isInvoke = true
    }else {
      timer = setTimeout(()=>{
        fn.apply(this,args)
        isInvoke = false
      },delay)
    }
  }
  _debounce.cancel = function() {
    if (timer) clearTimeout(timer)
    timer = null
    isInvoke = false
  }
  return _debounce
}

// 防抖返回值
function debounce4(fn, delay,immediate = false,callback= function(){}){
  let timer = null
  let isInvoke = false
  const _debounce = function(...args) {
    if (timer) clearTimeout(timer)
    if(immediate && !isInvoke){
      const result = fn.apply(this,args)
      callback(result)
      isInvoke = true
    }else {
      timer = setTimeout(()=>{
        const result = fn.apply(this,args)
        callback(result)
        isInvoke = false
      },delay)
    }
  }
  _debounce.cancel = function() {
    if (timer) clearTimeout(timer)
    timer = null
    isInvoke = false
  }
  return _debounce
}
// 节流
function throttle(fn, delay) {
    let flag = true,
        timer = null
    return function(...args) {
        let context = this
        if(!flag) return
        flag = false
        clearTimeout(timer)
        timer = setTimeout(function() {
            fn.apply(context,args)
            flag = true
        },delay)
    }
}

function throttle2(fn, delay) {
    let start = Date.now();
    return function() {
        let that = this;
        let args = arguments;
        //  获取当前时间，通过 当前时间 - 起点时间 =  时间差，，， 判断 时间差和 delay的关系
        let diff = Date.now() - start
        if (diff > delay) {
            fn.apply(that, args)
                // 初始化时间
            start = Date.now()
        }
    }
}

function throttle3(func, delay, timestamp=true) {
    let timer = null
    let pre = 0
    return function() {
      const context = this
      const args = arguments
      if(timestamp) {
        let now = Date.now()
        if(now - pre > delay) {
          pre = now
          //func.apply(context, args)
          func.call(context, ...args)
        }
      } else {
        if(!timer) {
          timer = setTimeout(() => {
            timer = null;
            // func.apply(context, args);
            func.call(context, ...args);
          }, delay)
        }
      }
    }
}

function fangdou(args){
    console.log('防抖' + args)
}

var a = debounce4(fangdou,3000,false)
a(1)
a(12)
a(123)
a(1234)
a(12345)

function jieliu(args){
    console.log('节流' + args)
}
var b = throttle(jieliu,3000)
b(456)
b(456)
b(456)

